# -*- coding: UTF-8 -*-
import md5
import os
import datetime

from pyramid.view import view_config
from pyramid.renderers import render_to_response
from pyramid.httpexceptions import HTTPFound
from sqlalchemy import and_, or_, desc

from pyramid.security import (
        remember,
        forget,
        IAuthenticationPolicy,
        )

from . import tz

from ..models.meta import (
    DBSession,
    )

from ..models.models import (
    ProductCategory,
    Product,
    ProductOrderDetail,
    User,
    Role,
    Coupon,
    CouponRandom,
    ProductOrder
    )

from ..freedom.dateutil.parser import parse
from ..freedom.randomserial import get_random_serial
from ..freedom.paginator import Paginator


@view_config(route_name='products_page1')
@view_config(route_name='products_page2')
@view_config(route_name='products_page3')
def products_page(request):
    id = request.matchdict.get('id')
    if id:
        if type(id) == int:
            exec('result = products_%s(request, %d)' % (request.matchdict.get('page') or 'index', int(id)))
        else:
            exec('result = products_%s(request, "%s")' % (request.matchdict.get('page') or 'index', id))
    else:
        exec('result = products_%s(request)' % request.matchdict.get('page') or 'index')

    return result


def products_detail(request, id):
    product = DBSession.query(Product).get(id)
    return render_to_response('/front/products/detail.html', {'product': product}, request = request)

def products_list(request):
    category_id = request.matchdict.get('category')
    
    tmpl_context = {}
    pagesize = 15

    #get current category
    if(category_id):
        category = DBSession.query(ProductCategory).get(int(category_id))
        tmpl_context['category'] = category
    else:
        tmpl_context['category'] = None

    #get products
    product_q = DBSession.query(Product).filter(Product.enable==True).filter(Product.deleted==False).order_by(desc(Product.recommended))
    if(category_id):
        product_q = product_q.filter(Product.category_id == int(category_id))

    paginator = Paginator(product_q, pagesize)
    paginator.page_from_url(request.url)

    tmpl_context['products'] = paginator

    #get the product category
    category_q = DBSession.query(ProductCategory).order_by(ProductCategory.priority)
    tmpl_context['categories'] = category_q

    return render_to_response('/front/products/list.html', tmpl_context, request = request)

def products_shoppingcart(request, id=0):
    details = request.session.has_key('shoppingcart') and request.session['shoppingcart'] or []
    if id != 0:
        #buy number
        number = int(request.params.get('number', 1))
        #get the product
        product = DBSession.query(Product).get(id)
        #save in session
        findDetail = [detail for detail in details if detail.product_id==id]
        newdetail = findDetail and findDetail[0] or ProductOrderDetail()
        newdetail.product_id = id
        newdetail.name = product.name
        newdetail.picture = product.picture
        newdetail.marketprice = product.marketprice
        newdetail.sellprice = product.sellprice
        newdetail.number = (newdetail.number or 0) + number

        if not findDetail:
            details.append(newdetail)

    request.session['shoppingcart'] = details

    #get the back url
    back_url = request.params.get('from', request.route_url('products_page2', page='list'))

    return render_to_response('/front/products/shoppingcart.html', {'back_url':back_url}, request = request)

def products_shoppingcartdelete(request, id):
    #get the product
    product = DBSession.query(Product).get(id)
    #delete from session
    if request.session.has_key('shoppingcart') and request.session['shoppingcart']:
        findDetail = [detail for detail in request.session['shoppingcart'] if detail.product_id==id]
        if findDetail:
            request.session['shoppingcart'].remove(findDetail[0])

    #get the back url
    back_url = request.params.get('from', request.route_url('products_page2', page='list'))

    return render_to_response('/front/products/shoppingcart.html', {'back_url':back_url}, request = request)


def products_createorder(request):
    tmpl_context = {}
    now = datetime.datetime.now(tz)
    #get current login user info
    user = DBSession.query(User).get(request.session['user_id'])

    if request.method=="GET":

        tmpl_context['user'] = user
        #get current shopping cart sum price
        sumPrice = 0
        if request.session.has_key('shoppingcart'):
            shoppingcart = request.session['shoppingcart']
            if shoppingcart:
                sumPrice = sum([detail.number*detail.sellprice for detail in shoppingcart])

        #load coupon info
        coupon_q = DBSession.query(Coupon).join(Coupon.couponrandoms)
        coupon_q = coupon_q.filter(Coupon.startdate<now).filter(Coupon.status==3).filter(Coupon.enddate>now)
        coupon_q = coupon_q.filter(CouponRandom.userid == user.id).filter(CouponRandom.isused==False)
        coupons = coupon_q.all()

        #filter, only show the avalable coupon
        coupons = [coupon for coupon in coupons if int(coupon.rule.split('/')[1]) <= sumPrice]
        tmpl_context['coupons'] = coupons

        return render_to_response('/front/products/createOrder.html', tmpl_context, request = request)


    if request.method=="POST":
        #update user info from the order
        user.realname = request.params.get('receiver')
        user.address = request.params.get('address')
        user.tel = request.params.get('tel')
        DBSession.add(user)

        #create order from session
        productOrder = ProductOrder()

        while True:
            productOrder.orderSN = str(now.year)[3] + str(now.month).rjust(2, '0') + str(now.day).rjust(2,'0') + get_random_serial(4)
            if DBSession.query(ProductOrder).filter(ProductOrder.orderSN == productOrder.orderSN).count() == 0:
                break
        productOrder.deliverAddress = request.params.get('address')
        productOrder.receiverName = request.params.get('receiver')
        productOrder.contactTel = request.params.get('tel')
        productOrder.orderStatus = 1
        if request.params.get('coupon'):
            couponRandom_q = DBSession.query(CouponRandom).join(CouponRandom.coupon)
            couponRandom_q = couponRandom_q.filter(CouponRandom.userid == user.id).filter(CouponRandom.isused==False)
            couponRandom_q = couponRandom_q.filter(Coupon.startdate<now).filter(Coupon.status==3).filter(Coupon.enddate>now)
            couponRandom_q = couponRandom_q.filter(Coupon.id == int(request.params.get('coupon')))
            couponRandoms = couponRandom_q.all()
            if len(couponRandoms) == 1:
                couponRandoms[0].isused = True #mark coupon used
                productOrder.couponRandom_id = couponRandoms[0].id

        DBSession.add(productOrder)
        if request.session.has_key('shoppingcart'):
            shoppingcart = request.session['shoppingcart']
            for detail in shoppingcart:
                detail.productOrder = productOrder
                DBSession.add(detail)

        #delete session info
        del request.session['shoppingcart']

        return HTTPFound(location = request.route_url('products_page3', page='createorderfinish', id=productOrder.orderSN))


def products_createorderfinish(request, orderSN):
    #get the order
    productOrder = DBSession.query(ProductOrder).filter(ProductOrder.orderSN == orderSN).first()
    return render_to_response('/front/products/createOrderFinish.html', {'productOrder':productOrder}, request = request)
